package com.spit.fammo.adapter

import android.view.View
import android.widget.Filter
import android.widget.Filterable
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import com.chad.library.adapter.base.BaseDelegateMultiAdapter
import com.chad.library.adapter.base.delegate.BaseMultiTypeDelegate
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.spit.fammo.R
import com.spit.fammo.bean.db.AssetBean
import com.spit.fammo.ext.ASSET_ALL_PAGE
import com.spit.fammo.ext.ASSET_FAIL_PAGE
import com.spit.fammo.ext.ASSET_NOT_PAGE
import com.spit.fammo.ext.ASSET_STOCK_PAGE
import com.spit.fammo.ext.setAdapterAnimation
import com.spit.fammo.util.SettingUtil

/**
 * @Author nike
 * @Date 2023/7/7 17:05
 * @Description
 */
class StockTakeAsetAdapter(data: ArrayList<AssetBean>) :
    BaseDelegateMultiAdapter<AssetBean, BaseViewHolder>(data), Filterable {

    init {
        setAdapterAnimation(SettingUtil.getListMode())

        setMultiTypeDelegate(object : BaseMultiTypeDelegate<AssetBean>() {
            override fun getItemType(data: List<AssetBean>, position: Int): Int {
                return data[position].type
            }
        })

        getMultiTypeDelegate()?.let {
            it.addItemType(ASSET_ALL_PAGE, R.layout.i_asset)
            it.addItemType(ASSET_STOCK_PAGE, R.layout.i_asset)
            it.addItemType(ASSET_NOT_PAGE, R.layout.i_asset)
            it.addItemType(ASSET_FAIL_PAGE, R.layout.i_fali_asset)
        }
    }

    override fun convert(viewHolder: BaseViewHolder, bean: AssetBean) {
        mFilterList[viewHolder.layoutPosition].run {
            viewHolder.setText(R.id.tv_title,  assetCode + " | " + name)
            viewHolder.setText(R.id.tv_brand,  brand)
            viewHolder.setText(R.id.tv_model,  model)
            viewHolder.setText(R.id.tv_category,  categoryName)
            viewHolder.setText(R.id.tv_location,  spaceLoc)
            viewHolder.setText(R.id.tv_epc,  epc)
            val iv_image = viewHolder.getView<AppCompatImageView>(R.id.iv_image)
            iv_image.visibility = if (type == ASSET_FAIL_PAGE) View.GONE else View.VISIBLE
            iv_image.background = if (stockTake)ContextCompat.getDrawable(context, R.mipmap.icon_2) else ContextCompat.getDrawable(context, R.mipmap.icon_3)
        }
    }

    var mFilterList = ArrayList<AssetBean>()

    fun appendList(list: List<AssetBean>) {
        data = list as MutableList<AssetBean>
        //这里需要初始化filterList
        mFilterList = list as ArrayList<AssetBean>
    }

    fun removeList(list: List<AssetBean>) {
        // 保留旧数据的副本，用于计算差异
        val oldList = this.mFilterList.toList()

        // 将需要删除的项的 uid 提取到一个集合中，便于快速查找
        val uidsToRemove = list.map { it.uid }.toSet()

        // 创建一个新列表，用于存储删除后的数据
        val newList = oldList.filter { !uidsToRemove.contains(it.uid) }

        // 使用 DiffUtil 计算差异
        val diffCallback = AssetDiffCallback(oldList, newList)
        val diffResult = DiffUtil.calculateDiff(diffCallback)

        // 更新数据源
        this.mFilterList.clear()
        this.mFilterList.addAll(newList)

        // 应用差异结果，更新 RecyclerView
        diffResult.dispatchUpdatesTo(this)
    }

    fun uploadList(list: List<AssetBean>) {
        // 保留旧数据的副本，用于计算差异
        val oldList = this.mFilterList.toList()

        // 使用 DiffUtil 计算差异
        val diffCallback = AssetDiffCallback(oldList, list)
        val diffResult = DiffUtil.calculateDiff(diffCallback)

        // 然后根据差异结果更新 mFilterList 中的数据
        // 注意：这里不再直接清空和重新填充 mFilterList
        // 而是根据 DiffUtil 的结果，逐项更新 mFilterList 中的数据
        for (i in list.indices) {
            // 如果在 oldList 中存在相同的 uid，则更新数据
            val oldItemIndex = oldList.indexOfFirst { it.uid == list[i].uid }
            if (oldItemIndex != -1) {
                this.mFilterList[oldItemIndex] = list[i]
            } else {
                // 如果是新数据，则添加到 mFilterList 中
                this.mFilterList.add(list[i])
            }
        }

        // 先应用差异结果，更新 RecyclerView
        diffResult.dispatchUpdatesTo(this)
    }

    fun addList(list: List<AssetBean>) {
        val diffCallback = AssetDiffCallback(this.mFilterList, list)
        val diffResult = DiffUtil.calculateDiff(diffCallback)
        this.mFilterList.addAll(list)
        diffResult.dispatchUpdatesTo(this)
    }

    override fun getFilter(): Filter {
        return object : Filter() {
            //执行过滤操作
            override fun performFiltering(charSequence: CharSequence): FilterResults {
                val charString = charSequence.toString()
                if (charString.isEmpty()) {
                    //没有过滤的内容，则使用源数据
                    mFilterList = data as ArrayList<AssetBean>
                } else {
                    val filteredList: MutableList<AssetBean> = ArrayList()
                    for (i in data.indices) {
                        val bean = data[i]
                        if (bean.assetno?.contains(charString, ignoreCase = true) == true
                            || bean.name?.contains(charString, ignoreCase = true) == true
                            || bean.model?.contains(charString, ignoreCase = true) == true
                            || bean.brand?.contains(charString, ignoreCase = true) == true
                            || bean.epc?.contains(charString, ignoreCase = true) == true
                        ) {
                            filteredList.add(bean)
                        }
                    }
                    mFilterList = filteredList as ArrayList<AssetBean>
                }
                val filterResults = FilterResults()
                filterResults.values = mFilterList
                return filterResults
            }

            //把过滤后的值返回出来
            override fun publishResults(charSequence: CharSequence, filterResults: FilterResults) {
                mFilterList = filterResults.values as ArrayList<AssetBean>
                notifyDataSetChanged()
            }
        }
    }

    override fun getItemCount(): Int {
        return mFilterList.size
    }

    override fun hashCode(): Int {
        return mFilterList.hashCode()
    }

}